<template>
  <Card class="tag" :bordered="false">
    <template #title> 标签列表 （{{ tag.pagination?.total ?? '-' }}） </template>
    <template #extra>
      <Button type="primary" size="small" @click="createNewData">
        <template #icon>
          <PlusOutlined />
        </template>
        创建新标签
      </Button>
    </template>
    <Space class="toolbar">
      <Space>
        <InputSearch
          :loading="loading.state.value"
          class="search"
          placeholder="输入关键词搜索"
          v-model:value="filterParams.keyword"
          @search="handleSearch"
        />
        <Button type="primary" :loading="loading.state.value" @click="resetParamsAndRefresh">
          <template #icon>
            <ReloadOutlined />
          </template>
          重置并刷新
        </Button>
      </Space>
      <Space>
        <Button type="primary" :disabled="!selectedIDs.length" @click="handleDeleteList">
          <template #icon>
            <DeleteOutlined />
          </template>
          批量删除
        </Button>
      </Space>
    </Space>
    <Divider />
    <Spin :spinning="loading.state.value">
      <Table
        :data-source="tag.data"
        rowKey="_id"
        :row-selection="{
          selectedRowKeys: selectedIDs,
          onChange: handleSelect,
        }"
        :pagination="{
          current: tag.pagination?.current_page,
          pageSize: tag.pagination?.per_page,
          total: tag.pagination?.total,
          showSizeChanger: true,
        }"
        @change="handlePaginate"
      >
        <TableColumn key="id" :width="60" title="ID" data-index="id" />
        <TableColumn key="name" :width="140" title="名称" data-index="name" />
        <TableColumn key="slug" :width="160" title="别名" data-index="slug" />
        <TableColumn key="description" title="描述" data-index="description" />
        <TableColumn key="articles_count" :width="80" title="文章" data-index="articles_count" />
        <TableColumn key="action" :width="240" title="操作" data-index="action">
          <template #default="{ record, index }">
            <ButtonGroup>
              <Button size="small" type="text" @click="editData(index)">
                <EditOutlined />编辑
              </Button>
              <Button size="small" type="text" :danger="true" @click="handleDelete(record)">
                <template #icon>
                  <DeleteOutlined />
                </template>
                删除
              </Button>
              <Button size="small" type="link" target="_blank" :href="getFETagPath(record.slug)">
                <template #icon>
                  <LinkOutlined />
                </template>
                查看
              </Button>
            </ButtonGroup>
          </template>
        </TableColumn>
      </Table>
    </Spin>

    <EditModal
      :title="activeEditData ? '编辑标签' : '新标签'"
      :visible="isVisibleModal"
      :tag="activeEditData"
      :onCancel="closeModal"
      :onSubmit="handleSubmit"
    />
  </Card>
</template>

<script lang="ts" setup>
import { ref, reactive, computed, onMounted } from 'vue'
import {
  PlusOutlined,
  ReloadOutlined,
  EditOutlined,
  DeleteOutlined,
  LinkOutlined,
} from '@ant-design/icons-vue'

import type { Tag } from '@/constants/tag'
import type { ResponsePaginationData } from '@/constants/request'
import EditModal from './editModal.vue'
import { getFETagPath } from '@/transformers/url'
import { getTags, deleteTag, deleteTags, putTag, createTag } from '@/store/tag'
import type { GetTagParams } from '@/store/tag'
import {
  Button,
  ButtonGroup,
  Card,
  Divider,
  InputSearch,
  Modal,
  Space,
  Spin,
  Table,
  TableColumn,
  TablePaginationConfig,
} from 'ant-design-vue'
import { useLoading } from '@/handcer'

const loading = useLoading()

// 列表数据
const tag = reactive<ResponsePaginationData<Tag>>({
  data: [],
  pagination: undefined,
})

// 多选
const selectedIDs = ref<Array<string>>([])
const handleSelect = (ids: any[]) => {
  selectedIDs.value = ids
}

// 过滤参数
const filterParams = reactive({
  keyword: '',
})

// 弹窗
const activeEditDataIndex = ref<number | null>(null)
const isVisibleModal = ref<boolean>(false)

const activeEditData = computed(() => {
  const index = activeEditDataIndex.value
  return index !== null ? tag.data[index] : null
})
const closeModal = () => {
  isVisibleModal.value = false
}

// 编辑创建
const editData = (index: number) => {
  activeEditDataIndex.value = index
  isVisibleModal.value = true
}
const createNewData = () => {
  activeEditDataIndex.value = null
  isVisibleModal.value = true
}

// 搜索
const handleSearch = () => {
  fetchData()
}

// 获取数据
const fetchData = (params?: GetTagParams) => {
  const getParams = { ...params }
  if (filterParams.keyword) {
    getParams.keyword = filterParams.keyword
  }
  loading.promise(getTags(getParams)).then((response) => {
    tag.data = response.data
    tag.pagination = response.pagination
  })
}

const resetParamsAndRefresh = () => {
  filterParams.keyword = ''
  fetchData()
}

// 翻页
const handlePaginate = (pagination: TablePaginationConfig) => {
  const { current, pageSize } = pagination
  fetchData({ page: current, per_page: pageSize })
}

// 重新刷新数据
const refreshData = () => {
  fetchData({
    page: tag.pagination?.current_page,
    per_page: tag.pagination?.per_page,
  })
}

// 单个删除
const handleDelete = (tag: Tag) => {
  Modal.confirm({
    title: `确定要删除标签 “${tag.name}” 吗？`,
    content: '删除后不可恢复',
    centered: true,
    onOk: () => {
      deleteTag(tag._id!).then(() => {
        refreshData()
      })
    },
  })
}

// 批量删除
const handleDeleteList = () => {
  const ids = selectedIDs.value
  Modal.confirm({
    title: `确定要删除 ${ids.length} 个标签吗？`,
    content: '删除后不可恢复',
    centered: true,
    onOk: () => {
      deleteTags(ids).then(() => {
        refreshData()
      })
    },
  })
}

// 提交表单
const handleSubmit = (tag: Tag) => {
  if (activeEditData.value) {
    putTag({
      ...activeEditData.value,
      ...tag,
    }).then(() => {
      closeModal()
      refreshData()
    })
  } else {
    createTag(tag).then(() => {
      closeModal()
      refreshData()
    })
  }
}

onMounted(() => {
  fetchData()
})
</script>

<style lang="less">
.tag {
  .toolbar {
    display: flex;
    justify-content: space-between;

    .search {
      width: 200px;
    }
  }
}
</style>
